import store from '@/store'
import { logout, saveToken } from '@/store/actions/login'
import { ApiResponse } from '@/types/data'
import { Toast } from 'antd-mobile'
import axios, { AxiosError } from 'axios'
import history from './history'
import { getToken } from './storage'

export const realNameUrl = 'http://geek.itheima.net'
export const baseURL = realNameUrl + '/v1_0'

const request = axios.create({
  baseURL: baseURL,
  timeout: 5000,
})

// 添加请求拦截器
request.interceptors.request.use(
  function (config) {
    // 在发送请求之前做些什么
    const token = getToken().token
    if (token) {
      config.headers!.Authorization = `Bearer ${token}`
    }
    return config
  },
  function (error) {
    // 对请求错误做些什么
    return Promise.reject(error)
  }
)

// 添加响应拦截器
request.interceptors.response.use(
  function (response) {
    // 对响应数据做点什么
    return response
  },
  async function (error: AxiosError<{ message: string }>) {
    // 对响应错误做点什么
    //1.服务器繁忙 没有给你响应的情况
    if (!error.response) {
      Toast.show('服务器繁忙')
      return Promise.reject(error)
    }

    //2.  401
    if (error.response.status === 401) {
      const token = getToken()
      if (token.token) {
        //token存在，这里刷新token，需要使用原始的axios请求（不需要走请求拦截器）
        try {
          const res = await axios.request<ApiResponse<{ token: string }>>({
            method: 'put',
            url: baseURL + '/authorizations',
            headers: {
              Authorization: 'Bearer ' + token.refresh_token,
            },
          })
          //dispatch某action 将token进行更新，更新到redux中/更新到了本地
          store.dispatch(
            saveToken({
              token: res.data.data.token,
              refresh_token: token.refresh_token,
            })
          )

          //直接的请求失败了，不可能让用户刷新页面重新请求，应该我们重新请求
          //将原来发送失败的那次请求，重新发送一次
          //console.log(error.config);就是当前这次请求的全部配置
          //这里请求时，携带的token,是失效的token 但是会重新走一遍请求拦截器 用新的token请求

          console.log(error.config)
          return request(error.config)
        } catch (e) {
          console.log(e, 'refresh_token失效了')
          //1.清除本地存储和redux的token
          store.dispatch(logout())
          history.replace({
            pathname: '/login',
            state: {
              //跳转时，携带上当前页的地址
              from: history.location.pathname,
            },
          })

          Toast.show('当前状态已过期，请重新登录')
          return Promise.reject(error)
        }
      } else {
        //直接拦截到登录页
        history.replace({
          pathname: '/login',
          state: {
            //跳转时，携带上当前页的地址
            from: history.location.pathname,
          },
        })

        Toast.show('当前状态未登录，请重新登录')
        return Promise.reject(error)
      }
    }

    //3.有响应，响应错误，给用户提示即可
    Toast.show(error.response?.data.message)
    return Promise.reject(error)
  }
)

export default request
